package com.chuantou.yuba.ui;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

import com.baidu.location.BDLocation;
import com.chuantou.yuba.R;
import com.chuantou.yuba.YBApp;
import com.chuantou.yuba.ui.fragment.ConversationFragment;
import com.chuantou.yuba.ui.fragment.HomeFragment;
import com.chuantou.yuba.ui.fragment.HomeTrendsFragment;
import com.chuantou.yuba.ui.fragment.NearByFragment;
import com.chuantou.yuba.ui.fragment.ProfileFragment;
import com.chuantou.yuba.util.AccountManager;
import com.chuantou.yuba.util.ChatUtils;
import com.chuantou.yuba.util.Constants;
import com.chuantou.yuba.util.FragmentUtil;
import com.chuantou.yuba.util.StackManager;
import com.chuantou.yuba.util.UiUtil;
import com.easemob.EMConnectionListener;
import com.easemob.EMError;
import com.easemob.chat.EMChat;
import com.easemob.chat.EMChatManager;
import com.easemob.chat.EMConversation;
import com.easemob.chat.EMMessage;
import com.easemob.chat.EMMessage.ChatType;
import com.easemob.util.NetUtils;
import com.umeng.update.UmengUpdateAgent;
import com.umeng.update.UpdateConfig;

public class MainActivity extends BaseActivity implements OnClickListener {
	private static final int REQUEST_CODE_FROM_PROFILE = 200;
	private View[] mNaviViews = new View[5];
	private View mHomeLayout;
	private View mNearyByLayout;
	private View mMessageLayout;
	private View mFollowTrendsLayout;
	private View mProfileLayout;
	private String mShowFragmentTag;
	private NewMessageBroadcastReceiver msgReceiver;
	// 未读消息textview
	private TextView mUnreadLabel;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (savedInstanceState != null && savedInstanceState.getBoolean(Constants.ACCOUNT_REMOVED, false)) {
			// 防止被移除后，没点确定按钮然后按了home键，长期在后台又进app导致的crash
			// 三个fragment里加的判断同理
			YBApp.get().logout(null);
			StackManager.finishAll();
			startActivity(new Intent(this, LoginActivity.class));
			return;
		} else if (savedInstanceState != null && savedInstanceState.getBoolean("isConflict", false)) {
			// 防止被T后，没点确定按钮然后按了home键，长期在后台又进app导致的crash
			// 三个fragment里加的判断同理
			YBApp.get().logout(null);
			StackManager.finishAll();
			startActivity(new Intent(this, LoginActivity.class));
			return;
		}
		setContentView(R.layout.main);
		setupViews();
		BDLocation location = YBApp.get().getLocation();
		if (location == null) {
			if (!isGPSOPen(this)) {
				showNoGPSDialog();
			} else {
				startGetLocation();
			}
		}
		if (getIntent().getBooleanExtra("conflict", false) && !isConflictDialogShow) {
			showConflictDialog();
		} else if (getIntent().getBooleanExtra(Constants.ACCOUNT_REMOVED, false) && !isAccountRemovedDialogShow) {
			showAccountRemovedDialog();
		}
		msgReceiver = new NewMessageBroadcastReceiver();
		ChatUtils.loginIM(this);
		// 注册一个接收消息的BroadcastReceiver
		msgReceiver = new NewMessageBroadcastReceiver();
		IntentFilter intentFilter = new IntentFilter(EMChatManager.getInstance().getNewMessageBroadcastAction());
		intentFilter.setPriority(3);
		registerReceiver(msgReceiver, intentFilter);

		// 注册一个ack回执消息的BroadcastReceiver
		IntentFilter ackMessageIntentFilter = new IntentFilter(EMChatManager.getInstance().getAckMessageBroadcastAction());
		ackMessageIntentFilter.setPriority(3);
		registerReceiver(ackMessageReceiver, ackMessageIntentFilter);

		// setContactListener监听联系人的变化等
		// EMContactManager.getInstance().setContactListener(new
		// MyContactListener());
		// 注册一个监听连接状态的listener
		EMChatManager.getInstance().addConnectionListener(new MyConnectionListener());
		// 注册群聊相关的listener
		// EMGroupManager.getInstance().addGroupChangeListener(new
		// MyGroupChangeListener());
		// 通知sdk，UI 已经初始化完毕，注册了相应的receiver和listener, 可以接受broadcast了
		EMChat.getInstance().setAppInited();
		UpdateConfig.setDebug(true);
		UmengUpdateAgent.setDeltaUpdate(false);
		UmengUpdateAgent.update(this);
	}

	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		if (getIntent().getBooleanExtra("conflict", false) && !isConflictDialogShow) {
			showConflictDialog();
		} else if (getIntent().getBooleanExtra(Constants.ACCOUNT_REMOVED, false) && !isAccountRemovedDialogShow) {
			showAccountRemovedDialog();
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		updateUnreadLabel();
		EMChatManager.getInstance().activityResumed();
		if (mNoGPSDialog != null && mNoGPSDialog.isShowing() && isGPSOPen(this)) {
			mNoGPSDialog.dismiss();
			startGetLocation();
		}
	}

	private AlertDialog mNoGPSDialog = null;

	private void showNoGPSDialog() {
		AlertDialog.Builder builder = new Builder(this);
		builder.setTitle(R.string.no_gprs_title);
		builder.setMessage(R.string.no_gprs_content);
		builder.setCancelable(false);
		builder.setPositiveButton(R.string.go_setting, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				Intent intent = new Intent();
				intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
				try {
					startActivity(intent);
				} catch (ActivityNotFoundException ex) {
					intent.setAction(Settings.ACTION_SETTINGS);
					try {
						startActivity(intent);
					} catch (Exception e) {
					}
				}
			}
		});
		mNoGPSDialog = builder.create();
		mNoGPSDialog.show();
	}

	private ProgressDialog mGetLocationDialog = null;

	private void startGetLocation() {
		mGetLocationDialog = new ProgressDialog(this);
		mGetLocationDialog.setMessage(getString(R.string.getting_current_location));
		mGetLocationDialog.setCancelable(false);
		mGetLocationDialog.show();
		new AsyncTask<Void, Void, BDLocation>() {
			private CountDownLatch mLatch = new CountDownLatch(1);

			@Override
			protected BDLocation doInBackground(Void... params) {
				BDLocation location = YBApp.get().getLocation();
				try {
					int waitCount = 0;
					while (location == null) {
						mLatch.await(1, TimeUnit.SECONDS);
						location = YBApp.get().getLocation();
						// 10秒后无结果直接返回
						if (waitCount >= 10) {
							break;
						}
						waitCount++;
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				return location;
			}

			protected void onPostExecute(BDLocation location) {
				if (hasDestroyed())
					return;
				mGetLocationDialog.dismiss();
				if (location == null) {
					showCannotGetLocationDialog();
				}
			};

		}.execute();
	}

	private void showCannotGetLocationDialog() {
		AlertDialog.Builder builder = new Builder(this);
		builder.setMessage(R.string.cannot_get_location_title);
		builder.setCancelable(false);
		builder.setPositiveButton(R.string.retry, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				startGetLocation();
			}
		});
		builder.create().show();
	}

	private boolean isGPSOPen(final Context context) {
		LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
		// 通过GPS卫星定位，定位级别可以精确到街（通过24颗卫星定位，在室外和空旷的地方定位准确、速度快）
		boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
		// 通过WLAN或移动网络(3G/2G)确定的位置（也称作AGPS，辅助GPS定位。主要用于在室内或遮盖物（建筑群或茂密的深林等）密集的地方定位）
		boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
		if (gps || network) {
			return true;
		}

		return false;
	}

	@Override
	protected void onDestroy() {
		// 注销广播接收者
		try {
			unregisterReceiver(msgReceiver);
		} catch (Exception e) {
		}
		try {
			unregisterReceiver(ackMessageReceiver);
		} catch (Exception e) {
		}

		// try {
		// unregisterReceiver(offlineMessageReceiver);
		// } catch (Exception e) {
		// }

		if (conflictBuilder != null) {
			conflictBuilder.create().dismiss();
			conflictBuilder = null;
		}
		if (mNoGPSDialog != null && mNoGPSDialog.isShowing()) {
			mNoGPSDialog.dismiss();
		}
		super.onDestroy();
	}

	private void setupViews() {
		mUnreadLabel = (TextView) findViewById(R.id.unread_msg_number);
		mHomeLayout = findViewById(R.id.home_layout);
		mHomeLayout.setOnClickListener(this);
		mNearyByLayout = findViewById(R.id.nearby_layout);
		mNearyByLayout.setOnClickListener(this);
		mMessageLayout = findViewById(R.id.message_layout);
		mMessageLayout.setOnClickListener(this);
		mFollowTrendsLayout = findViewById(R.id.follow_trends_layout);
		mFollowTrendsLayout.setOnClickListener(this);
		mProfileLayout = findViewById(R.id.profile_layout);
		mProfileLayout.setOnClickListener(this);
		mNaviViews[0] = mHomeLayout;
		mNaviViews[1] = mNearyByLayout;
		mNaviViews[2] = mMessageLayout;
		mNaviViews[3] = mFollowTrendsLayout;
		mNaviViews[4] = mProfileLayout;
		mHomeLayout.performClick();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.home_layout:
		case R.id.nearby_layout:
		case R.id.message_layout:
		case R.id.follow_trends_layout:
		case R.id.profile_layout:
			switchContentView(v.getId());
			break;
		default:
			break;
		}
	}

	private void switchContentView(int id) {
		// 先判断是否需要登录
		if (id == R.id.profile_layout || id == R.id.message_layout || id == R.id.follow_trends_layout) {
			if (!AccountManager.getInstance(getApplicationContext()).isLogined()) {
				UiUtil.showNoLoginDialog(this, REQUEST_CODE_FROM_PROFILE, LoginActivity.ACTION_RETURN);
				return;
			}
		}
		String tag = String.valueOf(id);
		FragmentManager fragmentManager = getSupportFragmentManager();
		FragmentUtil.hideAllFragment(fragmentManager);
		Fragment fragment = fragmentManager.findFragmentByTag(tag);
		FragmentTransaction transaction = fragmentManager.beginTransaction();
		if (fragment == null) {
			if (id == R.id.nearby_layout) {
				fragment = new NearByFragment();
			} else if (id == R.id.message_layout) {
				fragment = new ConversationFragment();
			} else if (id == R.id.follow_trends_layout) {
				fragment = new HomeTrendsFragment();
			} else if (id == R.id.profile_layout) {
				fragment = new ProfileFragment();
			} else {
				fragment = new HomeFragment();
			}
			transaction.add(R.id.content_layout, fragment, tag);
		} else {
			transaction.show(fragment);
		}
		transaction.commitAllowingStateLoss();
		for (View view : mNaviViews) {
			if (view.getId() == id) {
				view.setSelected(true);
			} else {
				view.setSelected(false);
			}
		}
		mShowFragmentTag = tag;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode != RESULT_OK) {
			super.onActivityResult(requestCode, resultCode, data);
			return;
		}
		if (requestCode == REQUEST_CODE_FROM_PROFILE) {
			mProfileLayout.performClick();
		} else if (requestCode == Constants.REQUEST_CODE_PICK_PHOTO || requestCode == Constants.REQUEST_CODE_TAKE_PHOTO) {
			FragmentManager fragmentManager = getSupportFragmentManager();
			if (!TextUtils.isEmpty(mShowFragmentTag)) {
				Fragment fragment = fragmentManager.findFragmentByTag(mShowFragmentTag);
				if (fragment != null) {
					fragment.onActivityResult(requestCode, resultCode, data);
				}
			}
		} else {
			super.onActivityResult(requestCode, resultCode, data);
		}
	}

	@Override
	public void onBackPressed() {
		Intent home = new Intent(Intent.ACTION_MAIN);  
		home.addCategory(Intent.CATEGORY_HOME);   
		startActivity(home); 
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		return super.onKeyDown(keyCode, event);
	}

	/**
	 * 消息回执BroadcastReceiver
	 */
	private BroadcastReceiver ackMessageReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			abortBroadcast();

			String msgid = intent.getStringExtra("msgid");
			String from = intent.getStringExtra("from");

			EMConversation conversation = EMChatManager.getInstance().getConversation(from);
			if (conversation != null) {
				// 把message设为已读
				EMMessage msg = conversation.getMessage(msgid);
				if (msg != null) {
					// 2014-11-5 修复在某些机器上，在聊天页面对方发送已读回执时不立即显示已读的bug
					if (ChatActivity.activityInstance != null) {
						if (msg.getChatType() == ChatType.Chat) {
							if (from.equals(ChatActivity.activityInstance.getToChatUid()))
								return;
						}
					}

					msg.isAcked = true;
				}
			}

		}
	};

	/**
	 * 新消息广播接收者
	 * 
	 * 
	 */
	private class NewMessageBroadcastReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			// 主页面收到消息后，主要为了提示未读，实际消息内容需要到chat页面查看

			String from = intent.getStringExtra("from");
			// 消息id
			String msgId = intent.getStringExtra("msgid");
			EMMessage message = EMChatManager.getInstance().getMessage(msgId);
			// 2014-10-22 修复在某些机器上，在聊天页面对方发消息过来时不立即显示内容的bug
			if (ChatActivity.activityInstance != null) {
				if (message.getChatType() == ChatType.GroupChat) {
					if (message.getTo().equals(ChatActivity.activityInstance.getToChatUid()))
						return;
				} else {
					if (from.equals(ChatActivity.activityInstance.getToChatUid()))
						return;
				}
			}

			// 注销广播接收者，否则在ChatActivity中会收到这个广播
			abortBroadcast();

			notifyNewMessage(message);

			// 刷新bottom bar消息未读数
			updateUnreadLabel();
			String messageTag = String.valueOf(R.id.message_layout);
			if (messageTag.equals(mShowFragmentTag)) {
				FragmentManager fragmentManager = getSupportFragmentManager();
				ConversationFragment fragment = (ConversationFragment) fragmentManager.findFragmentByTag(messageTag);
				// 当前页面如果为聊天历史页面，刷新此页面
				if (fragment != null) {
					fragment.refresh();
				}
			}

		}
	}

	/**
	 * 获取未读消息数
	 * 
	 * @return
	 */
	public int getUnreadMsgCountTotal() {
		int unreadMsgCountTotal = 0;
		unreadMsgCountTotal = EMChatManager.getInstance().getUnreadMsgsCount();
		return unreadMsgCountTotal;
	}

	/**
	 * 刷新未读消息数
	 */
	public void updateUnreadLabel() {
		int count = getUnreadMsgCountTotal();
		if (count > 0) {
			mUnreadLabel.setText(String.valueOf(count));
			mUnreadLabel.setVisibility(View.VISIBLE);
		} else {
			mUnreadLabel.setVisibility(View.INVISIBLE);
		}
	}

	/**
	 * 连接监听listener
	 * 
	 */
	private class MyConnectionListener implements EMConnectionListener {

		@Override
		public void onConnected() {
			runOnUiThread(new Runnable() {

				@Override
				public void run() {
					FragmentManager fragmentManager = getSupportFragmentManager();
					ConversationFragment fragment = (ConversationFragment) fragmentManager.findFragmentByTag(String.valueOf(R.id.message_layout));
					if (fragment != null && fragment.errorText != null) {
						fragment.errorText.setVisibility(View.GONE);
					}
				}
			});
		}

		@Override
		public void onDisconnected(final int error) {
			final String st1 = getResources().getString(R.string.less_than_chat_server_connection);
			final String st2 = getResources().getString(R.string.the_current_network);
			runOnUiThread(new Runnable() {

				@Override
				public void run() {
					if (error == EMError.USER_REMOVED) {
						// 显示帐号已经被移除
						showAccountRemovedDialog();
					} else if (error == EMError.CONNECTION_CONFLICT) {
						// 显示帐号在其他设备登陆dialog
						showConflictDialog();
					} else {
						FragmentManager fragmentManager = getSupportFragmentManager();
						ConversationFragment fragment = (ConversationFragment) fragmentManager.findFragmentByTag(String.valueOf(R.id.message_layout));
						if (fragment != null && fragment.errorText != null) {
							fragment.errorText.setVisibility(View.VISIBLE);
							if (NetUtils.hasNetwork(MainActivity.this))
								fragment.errorText.setText(st1);
							else
								fragment.errorText.setText(st2);
						}
					}
				}

			});
		}
	}

	private android.app.AlertDialog.Builder conflictBuilder;
	private android.app.AlertDialog.Builder accountRemovedBuilder;
	private boolean isConflictDialogShow;
	private boolean isAccountRemovedDialogShow;

	/**
	 * 显示帐号在别处登录dialog
	 */
	private void showConflictDialog() {
		isConflictDialogShow = true;
		YBApp.get().logout(null);
		String st = getResources().getString(R.string.logoff_notification);
		if (!MainActivity.this.isFinishing()) {
			// clear up global variables
			try {
				if (conflictBuilder == null)
					conflictBuilder = new android.app.AlertDialog.Builder(MainActivity.this);
				conflictBuilder.setTitle(st);
				conflictBuilder.setMessage(R.string.connect_conflict);
				conflictBuilder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
						conflictBuilder = null;
						StackManager.finishAll();
						startActivity(new Intent(MainActivity.this, LoginActivity.class));
					}
				});
				conflictBuilder.setCancelable(false);
				conflictBuilder.create().show();
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
	}

	/**
	 * 帐号被移除的dialog
	 */
	private void showAccountRemovedDialog() {
		isAccountRemovedDialogShow = true;
		YBApp.get().logout(null);
		String st5 = getResources().getString(R.string.remove_the_notification);
		if (!MainActivity.this.isFinishing()) {
			// clear up global variables
			try {
				if (accountRemovedBuilder == null)
					accountRemovedBuilder = new android.app.AlertDialog.Builder(MainActivity.this);
				accountRemovedBuilder.setTitle(st5);
				accountRemovedBuilder.setMessage(R.string.em_user_remove);
				accountRemovedBuilder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
						accountRemovedBuilder = null;
						StackManager.finishAll();
						startActivity(new Intent(MainActivity.this, LoginActivity.class));
					}
				});
				accountRemovedBuilder.setCancelable(false);
				accountRemovedBuilder.create().show();
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
	}

}
